using MapsterMapper;
using AiQiuQuan.Sport.Model.Models;
using AiQiuQuan.Sport.WebApi.Entities;
using AiQiuQuan.Sport.WebApi.Repositories;
using Microsoft.EntityFrameworkCore;
using AiQiuQuan.Sport.WebApi.Core;
using AiQiuQuan.Sport.Model.Enums;

namespace AiQiuQuan.Sport.WebApi.Services.Impl
{
    /// <summary>
    /// 活动、约球、比赛订单管理
    /// </summary>
    public class GameOrderService : IGameOrderService
    {
        private readonly IMapper _mapper;
        private readonly ICurrentInfo _currentInfo;
        private readonly IGameOrderRepository _gameOrderRepository;
        private readonly IActivityRepository _activityRepository;
        private readonly IRefundOrderRepository _refundOrderRepository;
        private readonly IGameRepository _gameRepository;

        /// <summary>
        /// ctor
        /// </summary>
        public GameOrderService(
            IMapper mapper,
            ICurrentInfo currentInfo,
            IGameOrderRepository gameOrderRepository,
            IActivityRepository activityRepository,
            IRefundOrderRepository refundOrderRepository,
            IGameRepository gameRepository)
        {
            _mapper = mapper;
            _currentInfo = currentInfo;
            _gameOrderRepository = gameOrderRepository;
            _activityRepository = activityRepository;
            _refundOrderRepository = refundOrderRepository;
            _gameRepository = gameRepository;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        public async Task<PageResult<GameOrderDto>> PageListAsync(GameOrderPageRequestDto request)
        {
            var result = PageResult.Empty<GameOrderDto>();
            var queryable = _gameOrderRepository.AsNoTracking();
            if (request.IsOnlySelf)
            {
                queryable = queryable.Where(m => m.UserId == _currentInfo.UserId);
                //if (request.OrderState.HasValue)
                //{
                //    var paidList = new List<GameOrderStateEnum> { GameOrderStateEnum.Paid, GameOrderStateEnum.PartialRefunded };
                //    queryable = request.OrderState.Value != GameOrderStateEnum.Paid
                //        ? queryable.Where(m => m.State == request.OrderState.Value)
                //        : queryable.Where(m => paidList.Contains(request.OrderState.Value));
                //}
            }

            if (request.IsPlatform)
            {
                var orderStateList = new List<GameOrderStateEnum> { GameOrderStateEnum.Paid, GameOrderStateEnum.Refunded, GameOrderStateEnum.PartialRefunded, GameOrderStateEnum.Completed };
                queryable = request.OrderState.HasValue
                    ? queryable.Where(m => m.State == request.OrderState.Value)
                    : queryable.Where(m => orderStateList.Contains(m.State));
            }
            else if (request.OrderState.HasValue)
            {
                queryable = queryable.Where(m => m.State == request.OrderState.Value);
            }

            if (!string.IsNullOrWhiteSpace(request.ProductName))
            {
                queryable = queryable.Where(m => m.Name.Contains(request.ProductName));
            }

            if (request.BusinessType.HasValue)
            {
                queryable = queryable.Where(m => m.BusinessType == request.BusinessType.Value);
            }

            if (!string.IsNullOrWhiteSpace(request.OrderNo))
            {
                queryable = queryable.Where(m => m.OrderNo.Contains(request.OrderNo));
            }

            if (request.Date.HasValue)
            {
                queryable = queryable.Where(m => m.CreateTime >= request.Date.Value.DateTime);
            }

            if (!string.IsNullOrWhiteSpace(request.PhoneNo))
            {
                queryable = queryable.Where(m => m.Mobile.Contains(request.PhoneNo));
            }

            if (!string.IsNullOrWhiteSpace(request.Name))
            {
                queryable = queryable.Where(m => m.UserName.Contains(request.Name));
            }

            if (!string.IsNullOrWhiteSpace(request.Address))
            {
                queryable = queryable.Where(m => m.Address.Contains(request.Address));
            }

            result = await queryable.OrderByDescending(m => m.CreateTime).PageListAsync<GameOrder, GameOrderDto>(request, _mapper);

            if (result.Result.Any())
            {
                foreach (var item in result.Result.GroupBy(m => m.BusinessType))
                {
                    //设置基础信息
                    await SetBaseInfoAsync(item.Key, item.ToArray());
                }
            }

            return result;
        }

        /// <summary>
        /// 比赛活动订单详情
        /// </summary>
        /// <param name="id">订单ID</param>
        public async Task<GameOrderDto> GetAsync(Guid id)
        {
            var entity = await _gameOrderRepository.FirstOrDefaultAsync(m => m.ID == id);
            if (entity == null)
            {
                return null;
            }

            var result = _mapper.Map<GameOrderDto>(entity);
            //设置基础信息
            await SetBaseInfoAsync(result.BusinessType, result);

            result.RefundOrderList = await _refundOrderRepository.Where(m => result.OrderNo == m.OrderNo).OrderBy(m => m.CreateTime).Select(m => _mapper.Map<RefundOrderDto>(m)).ToListAsync();

            return result;
        }

        #region private methods
        /// <summary>
        /// 基础信息
        /// </summary>
        private async Task SetBaseInfoAsync(BusinessTypeEnum businessType, params GameOrderDto[] list)
        {
            var gameState = GameStateEnum.Joining;
            var logoUrl = string.Empty;
            switch (businessType)
            {
                case BusinessTypeEnum.Activity:
                    var activity = await _activityRepository.FirstOrDefaultAsync(m => m.ID == list[0].BusinessId);
                    gameState = activity.State;
                    logoUrl = activity.Logo;
                    break;
                case BusinessTypeEnum.Ball:
                    break;
                case BusinessTypeEnum.Game:
                    var game = await _gameRepository.FirstOrDefaultAsync(m => m.ID == list[0].BusinessId);
                    gameState = game.State;
                    logoUrl = game.Logo;
                    break;
            }

            foreach (var item in list)
            {
                item.GameState = gameState;
                item.LogoUrl = logoUrl;
            }
        }
        #endregion
    }
}